package org.lanzier.common.sqlparse.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.lanzier.common.sqlparse.ISqlParse;
import org.lanzier.common.sqlparse.SqlResultForm;
import org.lanzier.common.utils.MapUtils;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * @author lansb sql parse
 */
@Component("sqlParse")
public class SqlParseImpl implements ISqlParse {
	// private static Logger logger = Logger.getLogger("sqlparse");
	public SqlResultForm parseNode(Node element,
			Map<String, String> simpleRequestMap)
			throws Exception {
		StringBuffer sb = new StringBuffer("");
		parseDynamicTags(element, sb, simpleRequestMap); // 获得原始的sql并存入对象sb
		SqlResultForm srf = new SqlResultForm(); 
		String orisql = sb.toString().replaceAll("( +)", " ").trim();
		srf.setOriSql(orisql);
		String parsedSql = orisql;
		CharSequence cs = parsedSql;
		//替换${}，替换为原始字符串
		Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}", Pattern.DOTALL);//
		Matcher matcher = pattern.matcher(cs);
		String content = "";
		while (matcher.find()) {
			content = matcher.group();
			String key = content.replace("${", "").replace("}", "");// 获取字段名称
			String value = simpleRequestMap.get(key);
			parsedSql = parsedSql.replace(content, value.replace("'", "''"));
		}
		//替换#{}
		cs = parsedSql;
		pattern = Pattern.compile("#\\{(.*?)\\}", Pattern.DOTALL);
		matcher = pattern.matcher(cs);
		List<String> keyList = new ArrayList<String>();// 待替换的变量
		List<Object> valueList = new ArrayList<Object>();// 存放执行的值
		while (matcher.find()) {
			content = matcher.group();
			parsedSql = parsedSql.replace(content, "?");
			content = content.replace("#{", "").replace("}", "");// 获取字段名称
			String[] contentarr = content.split(",");
			String key = contentarr[0];
			if(contentarr.length == 1) {//只有一个为varchar
				valueList.add(MapUtils.getString(simpleRequestMap, key));
			} else {
				if("string".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getString(simpleRequestMap, key));
				} else if ("int".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getInt(simpleRequestMap, key));
				} else if ("float".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getFloat(simpleRequestMap, key));
				} else if ("double".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getDouble(simpleRequestMap, key));
				} 
			}
			keyList.add(key);
		}
		srf.setKeyList(keyList);
		srf.setParsedSql(parsedSql);
		srf.setValueList(valueList);
		return srf;
	}
	public SqlResultForm parseString(String orisql, Map<String, String> simpleRequestMap) throws Exception {
		//实现如下:
		SqlResultForm srf = new SqlResultForm(); 
		List<String> keyList = new ArrayList<String>();// 待替换的变量
		List<Object> valueList = new ArrayList<Object>();// 存放执行的值
		srf.setOriSql(orisql);
		String parsedSql = orisql; 
		CharSequence cs = parsedSql;
		// 替换${}，替换为原始字符串
		Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}", Pattern.DOTALL);//
		Matcher matcher = pattern.matcher(cs);
		String content = "";
		while (matcher.find()) {
			content = matcher.group();
			String key = content.replace("${", "").replace("}", "");// 获取字段名称
			String value = simpleRequestMap.get(key);
			parsedSql = parsedSql.replace(content, value.replace("'", "''"));
		}
		// 替换#{}
		cs = parsedSql;
		pattern = Pattern.compile("#\\{(.*?)\\}", Pattern.DOTALL);
		matcher = pattern.matcher(cs);
		while (matcher.find()) {
			content = matcher.group();
			parsedSql = parsedSql.replace(content, "?");
			content = content.replace("#{", "").replace("}", "");// 获取字段名称
			String[] contentarr = content.split(",");
			String key = contentarr[0];
			if (contentarr.length == 1) {// 只有一个为varchar
				valueList.add(MapUtils.getString(simpleRequestMap, key));
			} else {
				if ("string".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getString(simpleRequestMap, key));
				} else if ("int".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getInt(simpleRequestMap, key));
				} else if ("float".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getFloat(simpleRequestMap, key));
				} else if ("double".endsWith(contentarr[1])) {
					valueList.add(MapUtils.getDouble(simpleRequestMap, key));
				}
			}
			keyList.add(key);
		}
		srf.setKeyList(keyList);
		srf.setParsedSql(parsedSql);
		srf.setValueList(valueList);
		return srf;
	}
	/**
	 * 组装sql
	 * 
	 * @param node
	 * @param sbsql
	 * @param parameter
	 * @throws Exception
	 */
	private void parseDynamicTags(Node node, StringBuffer sbsql, Map<String, String> parameter)
			throws Exception {
		NodeList children = node.getChildNodes();
		for (int i = 0, len = children.getLength(); i < len; i++) {
			Node child = (Node) children.item(i);
			String nodeName = child.getNodeName();
			if (child.getNodeType() == 4 || child.getNodeType() == 3) {
				String data = child.getNodeValue();
				sbsql.append(" " + data.replaceAll("(\t|\n|\r|(\r\n))", "").trim());
				continue;
			} 
			if ("isNotEmpty".equalsIgnoreCase(nodeName))
				isNotEmptyNode((Element) child, sbsql, parameter);
			else if ("isEmpty".equalsIgnoreCase(nodeName))
				isEmptyNode((Element) child, sbsql, parameter);
			else if ("isEqual".equalsIgnoreCase(nodeName))
				isEqualNode((Element) child, sbsql, parameter);
			else if ("isNotEqual".equalsIgnoreCase(nodeName))
				isNotEqualNode((Element) child, sbsql, parameter);
		}
	}

	/**
	 *@param node
	 *@param sbsql
	 *@param parameter
	 *@throws Exception
	 */
	private void isNotEmptyNode(Element node, StringBuffer sbsql, Map<String, String> parameter)
			throws Exception {
		String property = node.getAttribute("property");
		if (parameter.get(property) != null)
			parseDynamicTags(node, sbsql, parameter);
	}
	
	private void isEmptyNode(Element node, StringBuffer sbsql, Map<String, String> parameter)
		throws Exception {
		String property = node.getAttribute("property");
		if (parameter.get(property) == null)
			parseDynamicTags(node, sbsql, parameter);
	}
	private void isEqualNode(Element node, StringBuffer sbsql, Map<String, String> parameter)
		throws Exception {
		String property = node.getAttribute("property");
		String compareProperty = node.getAttribute("compareProperty");
		String compareValue = node.getAttribute("compareValue");
		if (compareProperty != null && parameter.get(property).equals(parameter.get(compareProperty))) 
			parseDynamicTags(node, sbsql, parameter);
		else if(parameter.get(property).equals(compareValue)) parseDynamicTags(node, sbsql, parameter);
	}
	private void isNotEqualNode(Element node, StringBuffer sbsql, Map<String, String> parameter)
	throws Exception {
		String property = node.getAttribute("property");
		String compareProperty = node.getAttribute("compareProperty");
		String compareValue = node.getAttribute("compareValue");
		if (compareProperty != null && parameter.get(property).equals(parameter.get(compareProperty))) 
			parseDynamicTags(node, sbsql, parameter);
		else if(parameter.get(property).equals(compareValue)) parseDynamicTags(node, sbsql, parameter);
	}
}
